package android.util.test;

import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import com.android.gallery3d.R;
import com.android.gallery3d.app.ActivityState;
import com.android.gallery3d.app.AlbumPage;
import com.android.gallery3d.app.AlbumSetDataLoader;
import com.android.gallery3d.app.Config;
import com.android.gallery3d.app.EyePosition;
import com.android.gallery3d.app.GalleryActionBar;
import com.android.gallery3d.app.LoadingListener;
import com.android.gallery3d.data.MediaDetails;
import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.data.MediaSet;
import com.android.gallery3d.data.Path;
import com.android.gallery3d.glrenderer.GLCanvas;
import com.android.gallery3d.ui.AlbumSetSlotRenderer;
import com.android.gallery3d.ui.DetailsHelper;
import com.android.gallery3d.ui.GLRoot;
import com.android.gallery3d.ui.GLView;
import com.android.gallery3d.ui.Log;
import com.android.gallery3d.ui.SelectionManager;
import com.android.gallery3d.ui.SlotView;
import com.android.gallery3d.ui.SynchronizedHandler;
import com.android.gallery3d.util.Future;
import com.android.gallery3d.util.GalleryUtils;

public class CustomPage extends ActivityState implements
		SelectionManager.SelectionListener, EyePosition.EyePositionListener,
		MediaSet.SyncListener {

	private static final String TAG = CustomPage.class.getSimpleName();

	private static final int REQUEST_DO_ANIMATION = 1;
	private static final int MSG_PICK_ALBUM = 0x01;

	private static final int BIT_LOADING_RELOAD = 1;
	private static final int BIT_LOADING_SYNC = 2;

	public static final String EXTRA_MEDIA_PATH = "media.path";
	public static final int CACHE_SIZE = 96;

	private Context mContext;
	// ActionBar
	private GalleryActionBar mActionBar;

	// private SelectionManager mSelectionManager;

	private SlotView mSlotView;
	private Config.AlbumSetPage mConfig;

	private AlbumSetSlotRenderer mCustomView;

	private MediaSet mMediaSet;
	private AlbumSetDataLoader mCustomDataLoader;

	// private ActionModeHandler mActionModeHandler;

	// private boolean mGetContent;
	// private boolean mGetAlbum;
	// private String mTitle;
	// private String mSubtitle;

	private EyePosition mEyePosition;
	private DetailsHelper mDetailsHelper;
	private MyDetailsSource mDetailsSource;

	// private int mSelectedAction;
	private Handler mHandler;

	private boolean mIsActive;

	private int mLoadingBits;

	private boolean mInitialSynced = false;

	private Future<Integer> mSyncTask;

	private boolean mShowDetails = false;

	private float mX;
	private float mY;
	private float mZ;

	@Override
	protected int getBackgroundColorId() {
		return R.color.album_background;
	}

	private final GLView mRootPane = new GLView() {
		private final float mMatrix[] = new float[16];
		float x;
		float y;

		protected void onLayout(boolean changeSize, int left, int top,
				int right, int bottom) {
			Log.d(TAG, "mRootPanl -- onLayout");
			mEyePosition.resetPosition();

			int slotViewTop = mActionBar.getHeight() + mConfig.paddingTop;
			int slotViewBottom = bottom - top - mConfig.paddingBottom;
			int slotViewRight = right - left;

			if (mShowDetails) {
				mDetailsHelper.layout(left, slotViewTop, right, bottom);
			} else {
				mCustomView.setHighlightItemPath(null);
			}
			mSlotView.layout(0, slotViewTop, slotViewRight, slotViewBottom);
		};

		protected void render(GLCanvas canvas) {
			Log.d(TAG, "mRootPanl -- render");

			canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
			GalleryUtils.setViewPointMatrix(mMatrix, getWidth() / 2 + mX,
					getHeight() / 2 + mY, mZ);
			canvas.multiplyMatrix(mMatrix, 0);
			super.render(canvas);
			canvas.restore();
		};

		// protected boolean onTouch(MotionEvent event) {
		// if (event.getAction() == MotionEvent.ACTION_DOWN) {
		// x = event.getX();
		// y = event.getY();
		// invalidate();
		// }
		// return false;

		// };
	};

	@Override
	public void onCreate(Bundle data, Bundle storedState) {
		super.onCreate(data, storedState);
		Log.d(TAG, "onCreate");

		initViews();
		initDatas(data);

		mActionBar = mActivity.getGalleryActionBar();
		mContext = mActivity.getAndroidContext();
		// mGetContent = data.getBoolean(GalleryActivity.KEY_GET_CONTENT,
		// false);
		// mGetAlbum = data.getBoolean(GalleryActivity.KEY_GET_ALBUM, false);
		// mTitle = data.getString(AlbumSetPage.KEY_SET_TITLE);
		// mSubtitle = data.getString(AlbumSetPage.KEY_SET_SUBTITLE);

		mEyePosition = new EyePosition(mContext, this);
		mDetailsSource = new MyDetailsSource();

		// 默认Cluster类型
		// mSelectedAction = data.getInt(AlbumSetPage.KEY_SELECTED_CLUSTER_TYPE,
		// FilterUtils.CLUSTER_BY_TIME);

		mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
			@Override
			public void handleMessage(Message msg) {
				switch (msg.what) {
				case MSG_PICK_ALBUM:
					pickAlbum(msg.arg1);
					break;
				default:
					throw new AssertionError(msg.what);
				}
			}
		};

	}

	private void pickAlbum(int slotSelected) {
		Log.d(TAG, "pickAlbum -- index: " + slotSelected);
	}

	@Override
	protected void onResume() {
		super.onResume();
		Log.d(TAG, "resume");
		mIsActive = true;
		setContentPane(mRootPane);

		setLoadingBit(BIT_LOADING_RELOAD);

		mCustomDataLoader.resume();
		mCustomView.resume();
		mEyePosition.resume();
		// mActionModeHandler.resume();

		if (!mInitialSynced) {
			setLoadingBit(BIT_LOADING_SYNC);
			mSyncTask = mMediaSet.requestSync(CustomPage.this);
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		Log.d(TAG, "onPause");

		mIsActive = false;

		mCustomDataLoader.pause();
		mCustomView.pause();
		mEyePosition.pause();
		// mActionModeHandler.pause();
		DetailsHelper.pause();

		if (mSyncTask != null) {
			mSyncTask.cancel();
			mSyncTask = null;
			clearLoadingBit(BIT_LOADING_SYNC);
		}
	}

	@Override
	protected boolean onCreateActionBar(Menu menu) {

		mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME);
		mActionBar.setDisplayOptions(true, true);
		mActionBar.setTitle("CustomPage");

		MenuInflater inflater = getSupportMenuInflater();

		inflater.inflate(R.menu.custom, menu);
		return true;
	}

	@Override
	protected boolean onItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			onBackPressed();
			break;
		case R.id.action_share:
			Log.d(TAG, "Menu -- ActionShare is click !");
			break;
		case R.id.action_save:
			Log.d(TAG, "Menu -- ActionSave is click !");
			break;
		case R.id.action_edit:
			Log.d(TAG, "Menu -- ActionEdit is click !");
			break;
		case R.id.action_delete:
			Log.d(TAG, "Menu -- ActionDelete is click !");
			break;
		default:
			break;
		}
		return super.onItemSelected(item);
	}

	@Override
	protected void onStateResult(int requestCode, int resultCode, Intent data) {
		Log.d(TAG, "onStateResult -- requestCode : " + requestCode
				+ " resultCode : " + resultCode);
		if (data != null
				&& data.getBooleanExtra(AlbumPage.KEY_EMPTY_ALBUM, false)) {
			// showEmptyAlbumToast(Toast.LENGTH_SHORT);
		}
		switch (requestCode) {
		case REQUEST_DO_ANIMATION: {
			mSlotView.startRisingAnimation();
		}
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		Log.d(TAG, "onDestory");
		// mActionModeHandler.destroy();
	}

	private void initDatas(Bundle bundle) {
		Log.d(TAG, "initDatas");
		String dataPath = bundle.getString(EXTRA_MEDIA_PATH);
		Log.d(TAG, "initDatas -- Path : " + dataPath);
		mMediaSet = mActivity.getDataManager().getMediaSet(dataPath);

		// mSelectionManager.setSourceMediaSet(mMediaSet);

		mCustomDataLoader = new AlbumSetDataLoader(mActivity, mMediaSet,
				CACHE_SIZE);
		mCustomDataLoader.setLoadingListener(new DataLoadingListener());

		mCustomView.setModel(mCustomDataLoader);
	}

	private void initViews() {
		Log.d(TAG, "initViews");

		// mSelectionManager = new SelectionManager(mActivity, true);
		// mSelectionManager.setSelectionListener(this);

		mConfig = Config.AlbumSetPage.get(mActivity);
		mSlotView = new SlotView(mActivity, mConfig.slotViewSpec);

		mCustomView = new AlbumSetSlotRenderer(mActivity, null, mSlotView,
				mConfig.labelSpec, mConfig.placeholderColor);
		// SlotView设置Render对象
		mSlotView.setSlotRenderer(mCustomView);

		mSlotView.setListener(new SlotView.SimpleListener() {

			@Override
			public void onUp(boolean followedByLongPress) {
				CustomPage.this.onUp(followedByLongPress);
			}

			@Override
			public void onSingleTapUp(int index) {
				CustomPage.this.onSingleTapUp(index);
			}

			@Override
			public void onScrollPositionChanged(int position, int total) {
				CustomPage.this.onScrollPositionChanged(position, total);
			}

			@Override
			public void onLongTap(int index) {
				CustomPage.this.onLongTap(index);
			}

			@Override
			public void onDown(int index) {
				CustomPage.this.onDown(index);
			}
		});

		// mActionModeHandler = new ActionModeHandler(mActivity,
		// mSelectionManager);
		// mActionModeHandler.setActionModeListener(new ActionModeListener() {
		//
		// @Override
		// public boolean onActionItemClicked(MenuItem item) {
		// return onItemSelected(item);
		// }
		// });
		mRootPane.addComponent(mSlotView);
	}

	private void onUp(boolean followedByLongPress) {
	}

	private void onSingleTapUp(int index) {
	}

	private void onScrollPositionChanged(int position, int total) {
	}

	private void onLongTap(int index) {
	}

	private void onDown(int index) {
	}

	@Override
	public void onSelectionModeChange(int mode) {

	}

	@Override
	public void onSelectionChange(Path path, boolean selected) {
		Log.d(TAG, "onSelectionChange");

		// mActionModeHandler.setTitle(getTitleByPath());
		// mActionModeHandler.updateSupportedOperation(path, selected);

	}

	@Override
	public void onEyePositionChanged(float x, float y, float z) {
		mRootPane.lockRendering();
		try {

			mX = x;
			mY = y;
			mZ = z;
		} finally {
			mRootPane.unlockRendering();
		}

		mRootPane.invalidate();
	}

	private void setLoadingBit(int loadingBit) {
		mLoadingBits |= loadingBit;
	}

	private void clearLoadingBit(int loadingBit) {
		mLoadingBits &= ~loadingBit;
		if (mLoadingBits == 0 && mIsActive) {
			if (mCustomDataLoader.size() == 0) {

				if (mActivity.getStateManager().getStateCount() > 0) {
					Intent result = new Intent();
					result.putExtra(AlbumPage.KEY_EMPTY_ALBUM, true);
					setStateResult(Activity.RESULT_OK, result);

					mActivity.getStateManager().finishState(this);
				} else {
					mSlotView.invalidate();
				}
				return;
			}
		}
	}

	private class MyDetailsSource implements DetailsHelper.DetailsSource {

		private int mIndex;

		@Override
		public int size() {
			return mCustomDataLoader.size();
		}

		@Override
		public int setIndex() {
			// Path id = mSelectionManager.getSelected(false).get(0);
			// mIndex = mCustomDataLoader.findSet(id);
			return mIndex;
		}

		@Override
		public MediaDetails getDetails() {
			MediaObject item = mCustomDataLoader.getMediaSet(mIndex);
			if (item != null) {
				mCustomView.setHighlightItemPath(item.getPath());
				return item.getDetails();
			} else {
				return null;
			}
		}
	}

	private class DataLoadingListener implements LoadingListener {

		@Override
		public void onLoadingStarted() {
			Log.d(TAG, "DataLoadingListener -- onLoadingStarted ! ");
			setLoadingBit(BIT_LOADING_RELOAD);
		}

		@Override
		public void onLoadingFinished(boolean loadingFailed) {
			Log.d(TAG, "DataLoadingListener -- onLoadingFinshed ! ");
			clearLoadingBit(BIT_LOADING_RELOAD);
		}
	}

	@Override
	public void onSyncDone(MediaSet mediaSet, final int resultCode) {
		Log.d(TAG, "onSyncDone");
		if (resultCode == MediaSet.SYNC_RESULT_ERROR) {
			Log.d(TAG, "onSyncDone -- resultCode is sync error !");
		}

		mActivity.runOnUiThread(new Runnable() {

			@Override
			public void run() {
				GLRoot mRoot = mActivity.getGLRoot();
				mRoot.lockRenderThread();

				try {
					if (resultCode == MediaSet.SYNC_RESULT_SUCCESS) {
						mInitialSynced = true;
					}
					clearLoadingBit(BIT_LOADING_SYNC);

					if (resultCode == MediaSet.SYNC_RESULT_ERROR && mIsActive) {
						Log.d(TAG, "faile to load media set !");
					}
				} catch (Exception e) {
					Log.d(TAG, "exception!!");
					// mRoot.unlockRenderThread();
				} finally {
					mRoot.unlockRenderThread();
				}
			}
		});
	}
}
